package com.sjx.boundarycallback.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;


/**
 * created sjx 22/03/28
 * 自定义可拖动半圆环
 * 逆时针： 3点方向向12点方向转，想象一下所生成的夹角是邻边除以斜边
 *
 * 邻边 = cos(角度对应弧度） * r
 *         对边 = sin(角度对应弧度） * r
 *
 * 顺时针： 12点方向向3点方向转，想象一下所生成的夹角是对边除以斜边
 *
 * 邻边 = sin(角度对应弧度） * r
 *         对边 = cos(角度对应弧度） * r
 *
 *         下文第一象限区域时之所以180 -angle，是因为此时生成的弧度角其实是（触摸点和圆心连线）和x轴正方向夹角的补角
 */
public class CustomSeekBarView extends View {

    private String TAG = "CustomSeekBarView";
    private int mWidth;
    private int mHeight;
    private int mStrokeWidth;
    private int mRadius;
    private RectF mRectF;
    private Paint mPaint;
    private int mCircleRadius;
    private float mCircleX, mCircleY, mMoveX, mMoveY, mCurrentProgress;


    public CustomSeekBarView(Context context) {
        this(context, null);
    }

    public CustomSeekBarView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomSeekBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mRectF = new RectF();
        mPaint = new Paint();
        mCurrentProgress = 0;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        mRadius = Math.min(w, h) / 2;
        mStrokeWidth = (int) (mRadius * 0.2);
        mCircleRadius = mStrokeWidth / 2;
        mCircleX = -(int) (mRadius - mStrokeWidth * 2);
        mCircleY = -mStrokeWidth / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        canvas.translate(mWidth / 2, mHeight / 2);
        drawMethod(canvas);
        canvas.restore();
    }

    private void drawMethod(Canvas canvas) {

//        绘制白色滑道
        int rectValue = (int) (mRadius - mStrokeWidth * 2);
        mRectF.set(-rectValue, -rectValue, rectValue, rectValue);
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mStrokeWidth);
        canvas.drawArc(mRectF, -180, 180, false, mPaint);

//        绘制黑色按钮
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(Color.BLACK);
        mPaint.setStrokeWidth(0);

        float cosX = (float) (Math.cos(Math.toRadians(mCurrentProgress))) * (rectValue);
        mCircleX = - cosX;
        mCircleY = (float) - ((Math.sin(Math.toRadians(mCurrentProgress)))*rectValue) ;
        Log.i(TAG, "onDrawdDot: presentNum = " + mCurrentProgress);

        canvas.drawCircle(mCircleX, mCircleY, mCircleRadius, mPaint);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean flag;
        mMoveX = event.getX() - mWidth / 2;
        mMoveY = event.getY() - mHeight / 2;
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                flag = isRange(mMoveX, mCircleX - 60, mCircleX + 60) && isRange(mMoveY, mCircleY - 60, mCircleY + 60);
                Log.i(TAG, "onTouchEvent: flag = " + flag);
                if (flag) {
                    return true;
                } else {
                    return false;
                }

            case MotionEvent.ACTION_MOVE:
                setMoveProgress();
                return true;

            case MotionEvent.ACTION_UP:
                return true;
        }
        return true;
    }

    /**
     * 单点触控触摸点是否在可滑动范围内
     * @return isRange --isRange = false 不可滑动， isRange = true 可滑动
     * @param move 触摸点坐标
     */
    private boolean isRange(float move, float min, float max) {
        Log.i(TAG, "isRange: move = " + move + "mCircleX = " + mCircleX + "mCircleY = " + mCircleY);
        return Math.max(move, min ) == Math.min(move, max);
    }


    /**
     * 确定滑块坐标并进行重绘滑块
     */
    private void setMoveProgress() {
        //获取当前触摸点，赋值给当前进度
        //圆心坐标（(getWidth()/2 ,(getHeight()/2）
        if (mMoveY > 0) return;
        double longX=Math.pow(mMoveX,2);
        double longY=Math.pow(mMoveY,2);
        double longDuibian= -mMoveY;
        double asin=Math.asin(longDuibian/(Math.sqrt(longX+longY)));
        //弧度转化为角度
        float angle=(float)Math.toDegrees(asin);
        if (mMoveX>0)
            angle=180-angle;
        if (angle>=180)
            angle=180;
        if (angle<0)
            angle=0;
        //角度等比例转换为进度
        mCurrentProgress = angle;
        invalidate();
    }
}
